//----------------------------------------------------------------------------
// command.h
//
// base for swine commands and command map
//
// Copyright (C) 2011 Neil Butterworth
//----------------------------------------------------------------------------

#ifndef INC_SWINE_COMMAND_H
#define INC_SWINE_COMMAND_H

#include <windows.h>
#include <map>
#include <string>
#include <iostream>
#include "cmdline.h"

//----------------------------------------------------------------------------

namespace Swine {

//----------------------------------------------------------------------------
// Command base class
//----------------------------------------------------------------------------

class Command {

	public:

		Command( const std::string & name, const std::string & help );
		virtual ~Command();

		std::string Name() const;
		std::string Help() const;

		virtual int Execute( CmdLine & cl ) const = 0;
		virtual BOOL ProcessControlMessages( HWND wnd, int ctrl, int msg ) const;
		virtual int DoDialog( int dres, CmdLine & cl ) const;
		virtual void InitDialog( HWND dlg, CmdLine & cl  ) const;

		static const Command * DialogCommand();
		static void SetDialogCommand( const Command * cmd );


	private:

		static const Command * mDialogCommand;
		std::string mName, mHelp;
};

BOOL CALLBACK DialogProc( HWND, UINT, WPARAM wParam, LPARAM  );

//----------------------------------------------------------------------------
// Singleton command dictionary
//----------------------------------------------------------------------------

class CommandDict {

	public:

		~CommandDict();

		void Add( const Command * cmd );
		const Command * Find( const std::string &  name ) const;

		void WriteHelp() const;
		std::string GetLongHelp( const std::string & name  ) const;

		static CommandDict & Instance();

	private:

		CommandDict();

		typedef std::map <std::string, const Command *> DictType;
		DictType  mDict;

};

//----------------------------------------------------------------------------
// Command adder
//----------------------------------------------------------------------------

template <typename CMD>
struct AddCommand {

	AddCommand() {
		static CMD c;
		//Command * p = new CMD;
		CommandDict::Instance().Add( &c );
	}

};

//----------------------------------------------------------------------------

} // namespace

#endif
